Was ist base.pm
?
Welche Probleme macht base.pm
?
Was sind die Konsequenzen?
base.pm
base.pm
wird verwendet, um @ISA
zu modifizieren:
z.B. use base 'Foo';
, um von der Klasse Foo
zu erben
base.pm
wird seit Perl 5.004 mit Perl ausgeliefert
base.pm
?Laut der Dokumentation ist:
1: use base qw(Mama Papa);
base.pm
?Laut der Dokumentation ist:
1: use base qw(Mama Papa);
im Wesentlichen äquivalent zu
1: BEGIN { 2: require Mama; 3: require Papa; 4: push @ISA, qw(Mama Papa); 5: };
base.pm
tut viel mehr, als die Dokumentation sagt
Problem durch Unterstützung von fields.pm
base.pm
setzt $VERSION
, falls vorher keine definiert war.
1: package Blurgh; 2: # keine $VERSION
base.pm
setzt $VERSION
, falls vorher keine definiert war.
1: package Blurgh; 2: # keine $VERSION 3: package Foo; 4: sub VERSION { 1 };
base.pm
setzt $VERSION
, falls vorher keine definiert war.
1: package Blurgh; 2: # keine $VERSION 3: package Foo; 4: sub VERSION { 1 }; 5: package Baz; 6: $VERSION = 2; 7: 8: package Bar; 9: use base qw'Foo Baz Blurgh';
base.pm
setzt $VERSION
, falls vorher keine definiert war.
1: package Blurgh; 2: # keine $VERSION 3: package Foo; 4: sub VERSION { 1 }; 5: package Baz; 6: $VERSION = 2; 7: 8: package Bar; 9: use base qw'Foo Baz Blurgh'; 10: 11: package main; 12: for $p (qw(Foo Baz Blurgh)) { 13: printf "%s: VERSION(): %s\t\$VERSION: %s\n", 14: $p, $p->VERSION, 15: ${$p\::VERSION}; 16: }
Module
1: package Blurgh; # keine $VERSION 2: sub schlomp { 1 }; 3: package Foo; sub VERSION { 1 }; sub schlomp { 42 }; 4: package Baz; $VERSION = 2;
Module
1: package Blurgh; # keine $VERSION 2: sub schlomp { 1 }; 3: package Foo; sub VERSION { 1 }; sub schlomp { 42 }; 4: package Baz; $VERSION = 2;
Ausgabe
1: Foo: VERSION(): 1 $VERSION: -1, set by base.pm 2: Baz: VERSION(): 2 $VERSION: 2 3: Blurgh: VERSION(): -1, set by base.pm $VERSION: -1, set by base.pm
base.pm
lädt nicht alle ModuleUnter Perl 5.6 lädt
base.pm
kein Modul, dessen $VERSION
schon mal angefasst wurde:
1: # Foo ist nicht geladen 2: BEGIN { 3: print "Debug: Foo VERSION: $Foo::VERSION"; 4: }
base.pm
lädt nicht alle ModuleUnter Perl 5.6 lädt
base.pm
kein Modul, dessen $VERSION
schon mal angefasst wurde:
1: # Foo ist nicht geladen 2: BEGIN { 3: print "Debug: Foo VERSION: $Foo::VERSION"; 4: } 5: 6: use base 'Foo'; 7: Foo->schlomp; 8: # Cannot locate method "schlomp" via package 'Foo' at ...
1: use base 'ExistiertNicht';
1: use base 'ExistiertNicht';
liefert den Fehler
1: Base class package "ExistiertNicht" is empty. 2: (Perhaps you need to 'use' the module 3: which defines that package first.)
Das ist schlecht!
Es versteckt die eigentliche Fehlerursache
Netzwerkfehler
Berechtigungsproblem,
Fehlende Datei
Nur, damit das Folgende funktioniert:
1: use Tie::Hash; 2: use base 'Tie::StdHash';
Es gibt keine Datei Tie/StdHash.pm
Tie::StdHash
lebt in Tie/Hash.pm
base.pm
hat mindestens 100 Zeilen Code, nur
um das folgende zu erreichen:
1: sub import { 2: my $class = shift; 3: 4: my $inheritor = caller(0);
1: if ( @_ and $_[0] eq '-norequire' ) { 2: shift @_; 3: } else { 4: for ( my @filename = @_ ) { 5: if ( $_ eq $inheritor ) { 6: warn "Class '$inheritor' tried to inherit from itself\n"; 7: }; 8: 9: s{::|'}{/}g; 10: require "$_.pm"; # dies if the file is not found 11: } 12: }
@ISA
1: { 2: no strict 'refs'; 3: # This is more efficient than push for the new MRO 4: # at least until the new MRO is fixed 5: @{"$inheritor\::ISA"} = (@{"$inheritor\::ISA"} , @_); 6: }; 7: }; 8: 9: "All your base are belong to us"
parent.pm
Leider will M. Schwern die Featureitis von base.pm
nicht mehr zurückdrehen.
Ich habe parent.pm
geschrieben, ein Modul, dem ich mehr vertraue.
Code siehe oben.
parent.pm
...
KEINE!
Fragen?